/**
 * This file is part of 1genia trampoline
 * Copyright (C) 2007 1genia (contact@1genia.com)
 *
 * This library is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; version 3 of the License. 
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details. 
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; see the file COPYING.TXT.  If not,
 * write to the Free Software Foundation, Inc., 51 Franklin Street,
 * Fifth Floor, Boston, MA 02110-1301, USA. 
 **/
package com.genia.toolbox.web.gwt.form.client.widget.item.impl;

import com.genia.toolbox.web.gwt.basics.client.GwtHelper;
import com.genia.toolbox.web.gwt.basics.client.i18n.GwtI18nMessage;
import com.genia.toolbox.web.gwt.basics.client.support.GwtObjectUtils;
import com.genia.toolbox.web.gwt.form.client.CssNames;
import com.genia.toolbox.web.gwt.form.client.form.Item;
import com.genia.toolbox.web.gwt.form.client.widget.item.ItemWidget;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Widget;

/**
 * the basic implementation of <code>SimpleItemWidget</code>. It is a
 * <code>Composite</code> that will be filled by its sub-classes.
 * 
 * @param <ITEM>
 *          the type of item handled by this widget.
 */
public abstract class AbstractItemWidget<ITEM extends Item>
    extends Composite
    implements ItemWidget
{
  /**
   * the listener that checks that the value of an item is acceptable.
   */
  private static final ValidateModifyListener VALIDATE_MODIFY_LISTENER = new ValidateModifyListener();

  /**
   * the current error message being displayed.
   */
  private transient GwtI18nMessage currentErrorMessage = null;

  /**
   * the item this object represents.
   */
  private transient final ITEM item;



  /**
   * constructor.
   * 
   * @param item
   *          the item this object represents
   */
  protected AbstractItemWidget(final ITEM item)
  {
    this.item = item;
  }



  /**
   * return the <code>SimpleItem</code> this object represents.
   * 
   * @return the <code>SimpleItem</code> this object represents
   */
  public ITEM getItem()
  {
    return item;
  }



  /**
   * returns an array containing all the widget that the setErrorMessage must
   * modify.
   * 
   * @return an array containing all the widget that the setErrorMessage must
   *         modify
   */
  protected abstract Widget[] getWidgetsToToggle();



  /**
   * the method that sets the main widget of this composite. It alsos init the
   * listener that checks for validity of the value of this object.
   * 
   * @param widget
   *          the main widget of this composite
   */
  @Override
  protected void initWidget(final Widget widget)
  {
    super.initWidget(widget);
    addModifyListener(VALIDATE_MODIFY_LISTENER);
  }



  /**
   * Display or hide the error message associated to this item. If message is
   * <code>null</code> and an error message is currently displayed, the message
   * is hidden. Otherwise, if message is not null, it is displayed as an error
   * message.
   * 
   * @param message
   *          the message to display, or <code>null</code> to hide the error.
   */
  public void setErrorMessage(final GwtI18nMessage message)
  {
    final Widget[] widgets = getWidgetsToToggle();
    if (GwtObjectUtils.nullSafeEquals(currentErrorMessage, message)) {
      return;
    }
    if (message == null) {
      for (Widget widget2 : widgets) {
        widget2.removeStyleName(CssNames.ERROR_VALIDATION_CSS_STYLE);
        widget2.setTitle(null);
      }
    }
    else {
      for (final Widget widget : widgets) {
        widget.addStyleName(CssNames.ERROR_VALIDATION_CSS_STYLE);
        GwtHelper.fillTitle(widget, message);
      }
    }
    currentErrorMessage = message;
  }

}
